﻿using System;
using System.Collections.Generic;

namespace TradeHelp.Utilities
{
    /// <summary>
    /// 
    /// </summary>
    public static class ComparerHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="compareFunc"></param>
        /// <returns></returns>
        public static IComparer<T> GetComparer<T>(Func<T, T, int> compareFunc)
        {
            return new FuncComparer<T>(compareFunc);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public static IComparer<T> GetKeyComparer<T, TKey>(Func<T, TKey> keySelector)
        {
            return new KeyComparer<T, TKey>(keySelector);
        }

        #region Helper Classes
        
        private class FuncComparer<T> : IComparer<T>
        {
            private readonly Func<T, T, int> _comparer;

            public FuncComparer(Func<T, T, int> comparer)
            {
                Invariant.CheckIsNull(comparer, "comparer");
                _comparer = comparer;
            }

            public int Compare(T x, T y)
            {
                return _comparer(x, y);
            }
        }

        private class KeyComparer<T, TKey> : IComparer<T>
        {
            private readonly Func<T, TKey> _keySelector;

            public KeyComparer(Func<T, TKey> keySelector)
            {
                Invariant.CheckIsNull(keySelector, "keySelector");
                _keySelector = keySelector;
            }

            public int Compare(T x, T y)
            {
                var xKey = _keySelector(x);
                var yKey = _keySelector(y);
                return Comparer<TKey>.Default.Compare(xKey, yKey);
            }
        }
        #endregion
    }
}